const fs = require('fs');
module.exports = class extends nirvana.Controller {
	constructor(){
		super();
	}
	/**
	 * jsfuck解释器
	 * @param {string} text 编码,@开头表示文件
	 * @param {string} [reverse=0] 是否编码
	 * @param {string} [method] alert表示用console.log替换
	 */
	jsfuckAction(param){
		let result = '';
		if (param.reverse == 1) {
			const jsfuck = require('jsfuck').JSFuck;
			let s = (param.text.slice(0,1) === '@')?fs.readFileSync(param.text.slice(1)).toString():param.text;
			result = jsfuck.encode(s);
		}
		else {
			let s = (param.text.slice(0,1) === '@')?fs.readFileSync(param.text.slice(1)).toString():param.text;
			if (param.method === 'alert') {
				global.alert = console.log;
				eval(s);
			} else result = eval(s).toString();
		}
		return result;
	}
	/**
	 * Brainfuck解释器
	 * @param {string} text 编码,@开头表示文件
	 */
	brainfuckAction(param){
		const Brainfuck = require('brainfuck-node');
		const brainfuck = new Brainfuck();
		let s = (param.text.slice(0,1) === '@')?fs.readFileSync(param.text.slice(1)).toString():param.text;
		let result = brainfuck.execute(s);
		return result.output;
	}
	/**
	 * 替换密码
	 * @param {string} text 密文
	 * @param {string} [cleartext] 原码
	 * @param {string} key 替换码
	 * @usage `1234567890-=~!@#$%^&*()_+qwertyuiop[]\QWERTYUIOP{}|asdfghjkl;'ASDFGHJKL:"zxcvbnm,./ZXCVBNM<>?
	 */
	replaceAction(param){
		let orig = param.cleartext || '`1234567890-=~!@#$%^&*()_+qwertyuiop[]\\QWERTYUIOP{}|asdfghjkl;\'ASDFGHJKL:"zxcvbnm,./ZXCVBNM<>?';
		let s = [];
		for(let i=0;i<param.text.length;i++){
			let k = param.key.indexOf(param.text[i]);
			if (k === -1) s.push(param.text[i]);
			else s.push(orig[k]);
		}
		return s.join('');
	}
	/**
	 * 栅栏密码
	 * @param {string} text 密文
	 */
	fenceAction(param){
		let s = [];
		for(let col=2;col<param.text.length-1;col++){
			if (param.text.length % col === 0) {
				let row = param.text.length / col;
				let _s = '';
				for(let i=0;i<col;i++){
					for(let j=0;j<row;j++) {
						_s += param.text[j*col+i];
					}
				}
				s.push(_s);
			}
		}
		return s.join('\n');
	}
	/**
	 * 变形栅栏(www)
	 * @param {string} text 密文
	 * @param {number} key 解密栏数
	 */
	wwwfenceAction(param){
		console.log('text长度=',param.text.length);
		let str = param.text, key = param.key;
		const bi = require('big-integer');
		let de_key = 2 * key - 2,
			len = bi(str.length).divide(de_key),
			r = bi(str.length).mod(de_key),
			s = 0,
			delist = [];
			
		for (let i=0;i<key;i++){
			delist.push('');
		}
		if (r === 0) {
			delist[0] += str.slice(0,len);
			s = len;
		} else {
			delist[0] += str.slice(0,len+1);
			s = len+1
		}
	
		for (let i=1;i<key-1;i++){
			let l = len*2;
			if (r > i) l += 1
			if (r > de_key-i) l += 1
	
			delist[i] += str.slice(s,s+l);
			s = s+l
		}
		delist[key-1] += str.slice(s);
		let destr = '', j = 0, flag = 0;
		for (let i=0;i<str.length;i++){
			destr += delist[j][0]
			delist[j] = delist[j].slice(1)
			if (j == key-1) flag = 0
			if (j == 0) flag = 1
			if (flag) j += 1
			else j -= 1
		}
		return destr;
	}
	/**
	 * 回文
	 * @param {string} file 密文
	 * @usage pcregrep -o "([A-Z])([0-9])[a-z]\2\1|([0-9])([A-Z])[a-z]\4\3" file
	 */
	palindromeAction(param){
		let s = fs.readFileSync(param.file).toString();
		let m = s.match(/([A-Z])([0-9])[a-z]\2\1|([0-9])([A-Z])[a-z]\4\3/g);
		return m.map(c => {return c[2]}).join('');
	}
}